package com.valuedaas.schoolsafety.service.user;

import com.google.common.base.Enums;
import com.valuedaas.schoolsafety.common.collects.OrgUnit;
import com.valuedaas.schoolsafety.common.collects.sys.SysRole;
import com.valuedaas.schoolsafety.common.collects.sys.SysUser;
import com.valuedaas.schoolsafety.common.enums.DataStatus;
import com.valuedaas.schoolsafety.common.enums.UserState;
import com.valuedaas.schoolsafety.controller.permission.vo.Role;
import com.valuedaas.schoolsafety.controller.user.vo.User;
import com.valuedaas.schoolsafety.service.BaseService;
import com.valuedaas.schoolsafety.service.organization.OrgService;
import com.valuedaas.schoolsafety.util.SecurityUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserService extends BaseService {

    @Autowired
    OrgService orgService;

    @Override
    protected String collName() {
        return SysUser.COLL_NAME;
    }

    /**
     * 根据用户名和密码 查询用户信息
     *
     * @param username
     * @param password
     * @return @see User
     */
    public User login(String username, String password) {
        String passwordMd5 = SecurityUtil.genMd5Password(username, password);
        return loginWithMd5Pwd(username, passwordMd5);
    }

    public User loginWithMd5Pwd(String username, String md5Pwd) {
        Document userDoc = mongoTemplate.getCollection(collName())
                .find(
                        new Document(SysUser.USERNAME, username)
                                .append(SysUser.PASSWORD, md5Pwd)
                                .append(SysUser.META_STATUS, new Document("$ne", DataStatus.DELETE.name()))
                )
                .projection(new Document(SysUser.PASSWORD, 0)).first();
        return getUserWithRolesInfo(userDoc);
    }

    @SuppressWarnings("unchecked")
    private User getUserWithRolesInfo(Document userDoc) {
        if (userDoc == null) {
            return null;
        }
        // 获取用户的所有角色信息
        List<ObjectId> roleIds = (List<ObjectId>) userDoc.get(SysUser.ROLES);
        if (roleIds != null) {
            Document filter = new Document(SysUser._ID, new Document("$in", roleIds));
            List<Document> roles = new ArrayList<Document>();
            mongoTemplate.getCollection(SysUser.COLL_NAME).find(filter).into(roles);
            userDoc.put("roles", roles);
        }
        User user = new User();
        user.setRealname(userDoc.getString("realname"));
        user.setUsername(userDoc.getString(SysUser.USERNAME));
        user.setNickname(userDoc.getString(SysUser.NICKNAME));
        user.setRealname(userDoc.getString(SysUser.REALNAME));
        user.setEmail(userDoc.getString(SysUser.EMAIL));
        user.setUnitId(
                userDoc.getObjectId(SysUser.UNITID) == null ? null : userDoc.getObjectId(SysUser.UNITID).toString());
        if (StringUtils.isNotEmpty(user.getUnitId())) {
            Document orgDoc = orgService.get(user.getUnitId());
            if (orgDoc != null) {
                user.setUnitName(orgDoc.getString(OrgUnit.NAME));
            }
        }
        user.setUserId(userDoc.getObjectId(SysUser._ID).toString());
        user.setAvatar(userDoc.getString(SysUser.AVATAR));
        user.setSex(userDoc.getString(SysUser.SEX));
        user.setState(Enums.getIfPresent(UserState.class, userDoc.getString(SysUser.STATE)).orNull());

        //角色
        List<Role> roles = new ArrayList<Role>();
        List<Document> roleDocs = (List<Document>) userDoc.get(SysUser.ROLES);
        if (roleDocs != null) {
            for (Document roleDoc : roleDocs) {
                Role role = new Role();
                role.setDesc(roleDoc.getString(SysRole.DESC));
                role.setName(roleDoc.getString(SysRole.NAME));
                role.setRoleKey(roleDoc.getString(SysRole.KEY));
                role.setRoleId(roleDoc.getObjectId(SysRole._ID).toString());
                roles.add(role);
            }
        }
        user.setRoles(roles);
        return user;
    }

}
